package A1_栈和队列;

import java.util.*;

public class LC_347前K个高频元素_比较器 {
    public static void main(String[] args){
        int[] nums = {1,1,1,2,2,3};
        int k = 2;
        System.out.println(topKFrequent(nums,k));
    }
    public static int[] topKFrequent(int[] nums, int k) {
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(nums[i]))
                map.put(nums[i],map.get(nums[i])+1);
            else
                map.put(nums[i],1);
        }
        //比较器
        PriorityQueue<Integer> pq=new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return map.get(o1)-map.get(o2);
            }
        });
        for(int num:map.keySet()){//映射
            if(pq.size()<k)
                pq.add(num);
            else if(map.get(num)>map.get(pq.peek())){
                pq.remove();
                pq.add(num);
            }
        }

        int[] res=new int[k];
        for(int i=0;i<k;i++){
           res[i]= pq.remove();
        }
        return res;
    }
}
/*
 * Map集合中提供了get()获取元素的方法,get()对应一个键取出其对应的值，这种方式比较局限和单一，不能全部取出。
 * 要取出所有的元素(值)，则必须要拿到所有的键，然后才能取到所有与其对应的值，针对这种新的需求，Java中提了相应的解决方案
 * 解决方案:
 * Map集合中提供了两种取出方式:
 * <1>.返回值类型Set<k>方法是: keySet():返回此映射中包含的键的Set视图
 *     将map中所有的键存入到Set集合，因为set具备迭代器，所有迭代方式取出所有的键再根据get()方法，获取每一个键对应的值
 * <2>．返回值类型: Set<Map.Entry<K,V>>方法是: entrySet()
 *      取出的是关系，关系中包含key和value,其中Map.Entry<k,V>来表示这种数据类型
 *      即:将map集合中的映射关系存入到set集合中，这个关系的数据类型为:Map.Entry
 * Map.Entry接口：
 * 此接口在java.util包中，其实Entry也是一个接口，它是Map接口中的一个内部接口,
 * getKey()和getValue是接口Map.Entry<K,V>中的方法，返回对应的键和对应的值
 *
 * Map集合中是没有迭代器的，Map集合取出键值的原理:将map集合转成set集合，再通过迭代器取出
 */
